home *** CD-ROM | disk | FTP | other *** search
/ NeXT Education Software Sampler 1992 Fall / NeXT Education Software Sampler 1992 Fall.iso / Programming / Source / winterp-1.13 / src-client / wl-tcpip.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-06  |  7.8 KB  |  224 lines

  1. /* -*-C-*-
  2. ********************************************************************************
  3. *
  4. * File:         wl-tcpip.c
  5. * RCS:          $Header: wl-tcpip.c,v 1.7 91/04/22 00:34:30 mayer Exp $
  6. * Description:  TCP INET CLIENT to send lisp expressions to WINTERP lisp-server.
  7. *               (this code derived from examples in HP manual 50952-9000
  8. *               "ARPA Services/300 User's Guide" (pp 4-32 to 4-36)).
  9. * Author:       Niels Mayer, HPLabs
  10. * Created:      Sat Jun 10 02:15:35 1989
  11. * Modified:     Sat Oct  5 22:44:01 1991 (Niels Mayer) mayer@hplnpm
  12. * Language:     C
  13. * Package:      N/A
  14. * Status:       X11r5 contrib tape release
  15. *
  16. * WINTERP Copyright 1989-1991 Hewlett-Packard Company (by Niels Mayer).
  17. * XLISP version 2.1, Copyright (c) 1989, by David Betz.
  18. *
  19. * Permission to use, copy, modify, distribute, and sell this software and its
  20. * documentation for any purpose is hereby granted without fee, provided that
  21. * the above copyright notice appear in all copies and that both that
  22. * copyright notice and this permission notice appear in supporting
  23. * documentation, and that the name of Hewlett-Packard and David Betz not be
  24. * used in advertising or publicity pertaining to distribution of the software
  25. * without specific, written prior permission.  Hewlett-Packard and David Betz
  26. * make no representations about the suitability of this software for any
  27. * purpose. It is provided "as is" without express or implied warranty.
  28. *
  29. * HEWLETT-PACKARD AND DAVID BETZ DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
  30. * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
  31. * IN NO EVENT SHALL HEWLETT-PACKARD NOR DAVID BETZ BE LIABLE FOR ANY SPECIAL,
  32. * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  33. * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  34. * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  35. * PERFORMANCE OF THIS SOFTWARE.
  36. *
  37. * See ./winterp/COPYRIGHT for information on contacting the authors.
  38. * Please send modifications, improvements and bugfixes to mayer@hplabs.hp.com
  39. * Post XLISP-specific questions/information to the newsgroup comp.lang.lisp.x
  40. *
  41. ********************************************************************************
  42. */
  43. static char rcs_identity[] = "@(#)$Header: wl-tcpip.c,v 1.7 91/04/22 00:34:30 mayer Exp $";
  44.  
  45. #include <stdio.h>
  46. #include <sys/types.h>
  47. #include <sys/socket.h>
  48. #include <netinet/in.h>
  49. #include <netdb.h>
  50. #include "../src-server/config.h" /* defines DEFAULT_INET_SERVICE_PORT, etc */
  51.  
  52. char *progname = NULL;
  53.  
  54.  
  55. /*******************************************************************************
  56.  * Send <message> to the server via socket <s>
  57.  *******************************************************************************/
  58. void Server_Send(s, message)
  59.      int s;
  60.      char *message;
  61. {
  62.   if (send(s, message, strlen(message), 0) < 0) {
  63.     perror(progname);
  64.     fprintf(stderr, "%s: unable to send() on INET Domain Socket.\n", progname);
  65.     exit(1);
  66.   }
  67. }
  68.  
  69.  
  70. /*******************************************************************************
  71.  * Establish a connection with server process, returning socket descriptor
  72.  * if successful.
  73. *******************************************************************************/
  74. int Server_Connect(serverhost, port)
  75.      char *serverhost;
  76.      u_short port;
  77. {
  78.   int s;            /* connected socket descriptor */
  79.   struct hostent *hp;        /* pointer to host info for remote host */
  80.   struct servent *sp;        /* service information pointer */
  81.   struct sockaddr_in peeraddr_in; /* for peer socket address */
  82.  
  83.   /* clear out address structures */
  84.   memset((char *)&peeraddr_in, 0, sizeof(struct sockaddr_in));
  85.   
  86.   /* Set up the peer address to which we will connect. */
  87.   peeraddr_in.sin_family = AF_INET;
  88.  
  89.   /*
  90.    * Get the host information for the hostname that the
  91.    * user passed in. If serverhost==NULL, then make a quicker connection
  92.    * by bypassing search in /etc/hosts and using loopback adrs directly.
  93.    */
  94.   if (serverhost) {
  95.     if ((hp = gethostbyname(serverhost)) == NULL) {
  96.       fprintf(stderr, "%s: unable to find INET server host %s in /etc/hosts or from YP.\n",
  97.           progname, serverhost);
  98.       exit(1);
  99.     }
  100.     peeraddr_in.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr;
  101.   }
  102.   else {
  103.     peeraddr_in.sin_addr.s_addr = inet_addr(DEFAULT_INET_SERVICE_HOSTADDR); /* loopback */
  104.   }
  105.  
  106.   if (port == 0) {
  107.     /* get port number for service "widget_interp" */
  108.     if ((sp = getservbyname(DEFAULT_INET_SERVICE_NAME, "tcp")) == NULL) {    
  109.       fprintf(stderr, "%s: unable to find \"%s\" in /etc/services.\n",
  110.           progname,
  111.           DEFAULT_INET_SERVICE_NAME);
  112.       exit(1);
  113.     }
  114.     peeraddr_in.sin_port = sp->s_port;
  115.   }
  116.   else
  117.     peeraddr_in.sin_port = htons(port);
  118.   
  119.   /* Create the socket. */
  120.   if ((s = socket(AF_INET, SOCK_STREAM, 0))== -1) {
  121.     perror(progname);
  122.     fprintf(stderr, "%s: unable to create INET Domain Socket().\n", progname);
  123.     exit(1);
  124.   }
  125.  
  126.   /*
  127.    * Try to connect to the remote server at the address
  128.    * which was just built into peeraddr.
  129.    */
  130.   if (connect(s, &peeraddr_in, sizeof(struct sockaddr_in)) == -1) {
  131.     perror(progname);
  132.     fprintf(stderr, "%s: unable to connect() to remote via INET.\n", progname);
  133.     exit(1);
  134.   }
  135.  
  136.   return(s);
  137. }
  138.  
  139.  
  140. /******************************************************************************
  141.  * Server_Disconnect -- shutdown the connection for further sends. This causes
  142.  * the server to receive an EOF condition after it has received all data from
  143.  * Server_Send().
  144. ******************************************************************************/
  145. void Server_Disconnect(s)
  146.      int s;
  147. {
  148.   char buffer[200];
  149.   int length;
  150.  
  151.   if (shutdown(s, 1) == -1) {
  152.     perror(progname);
  153.     fprintf(stderr, "%s: unable to shutdown() INET Domain Socket.\n", progname);
  154.     exit(1);
  155.   }
  156. }
  157.  
  158.  
  159. /******************************************************************************
  160.  *
  161.  ******************************************************************************/
  162. main(argc, argv)
  163.      int argc;
  164.      char *argv[];
  165. {
  166.   extern int getopt();        /* proc to get option letter from argv */
  167.   extern char* optarg;        /* arg string being pointed to by getopt() */
  168.   extern int optind;        /* index into argv set by getopt() */
  169.   int opt;            /* option argument */
  170.   char hostname[200];        /* for holding server host name */
  171.   int hostname_given = 0;    /* true if hostname was spec'd by user */
  172.   int s;            /* connected socket desriptor */
  173.   u_short port = 0;        /* port number */
  174.   char* portstr;
  175.   char* hoststr;
  176.  
  177.   progname = argv[0];
  178.  
  179.   while ((opt = getopt(argc, argv, "h:p:")) != EOF)
  180.     switch (opt) {
  181.     case 'h':
  182.       strcpy(hostname, optarg);
  183.       hostname_given = 1;
  184.       break;
  185.     case 'p':
  186.       port = atoi(optarg);
  187.       break;
  188.     case '?':
  189.       fprintf(stderr, "usage: %s [-h hostname] [-p port] [sexpr]\n", progname);
  190.       exit (1);
  191.       break;
  192.     }
  193.  
  194.   if (port == 0) {
  195.     if ((portstr = (char *) getenv(DEFAULT_INET_PORT_ENVVAR)) != NULL) /* DEFAULT_INET_PORT_ENVVAR in "../src-server/config.h" */
  196.       port = (u_short) atoi(portstr);
  197.     else
  198.       port = DEFAULT_INET_SERVICE_PORT; /* default port # for winterp server */
  199.   }
  200.  
  201.   if (hostname_given)
  202.     s = Server_Connect(hostname, port); /* a remote connection w/ host spec'd on command line */
  203.   else {
  204.     if ((hoststr = (char *) getenv(DEFAULT_INET_HOSTADDR_ENVVAR)) != NULL) /* DEFAULT_INET_HOSTADDR_ENVVAR in "../src-server/config.h" */
  205.       s = Server_Connect(hoststr, port); /* use hostname given in environment var */
  206.     else
  207.       s = Server_Connect(NULL, port); /* a local connection -- use loopback */
  208.   }
  209.  
  210.   /*
  211.    * note that due to a bug/feature of winterp, we must send it only
  212.    * one sexp. Here, in the case that multiple args get passed, we also
  213.    * want to ensure that they're whitespace separated for tokenization
  214.    */
  215.   for (; optind < argc; optind++) {
  216.     Server_Send(s, argv[optind]);
  217.     Server_Send(s, " ");
  218.   }
  219.  
  220.   Server_Disconnect(s);
  221.   exit(0);
  222. }
  223.